package com.aisile.student.service.impl;

import cn.hutool.crypto.digest.MD5;

import com.aisile.model.base.vos.R;
import com.aisile.model.student.dtos.LoginDto;
import com.aisile.model.student.pojos.User;
import com.aisile.student.mapper.UserMapper;
import com.aisile.student.service.LoginService;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.gson.Gson;
import org.elasticsearch.common.collect.HppcMaps;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @Auther:yry
 * @Date:2024/6/17 0017
 * @VERSON:1.0
 */
@Service
@SuppressWarnings("ALL")
public class LoginServiceImpl implements LoginService {


    @Autowired
    private UserMapper userMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public R login(LoginDto dto) {
        // 查询 各种方式 自己研究
        Gson gson = new Gson();
        // 先判断dto
        if (dto == null) {
            return R.fail("必须传递用户名或者密码，缺一不可！");
        }
        if (dto.getName() == null || "".equals(dto.getName().trim())) {
            return R.fail("用户名或者手机号 不能为空！");
        }
        if (dto.getPassword() == null || "".equals(dto.getPassword().trim())) {
            return R.fail("密码不能为空！");
        }
        // 先看一下 当前账号是否在锁定中 根据用户名唯一原则
        String isLock = stringRedisTemplate.opsForValue().get("lock_" + dto.getName());
        if (isLock != null || isLock.equals("1")) {
            return R.fail("当前账号被锁定，1小时内不允许登录！");
        }
        // 查询数据库  根据用户名或者手机号进行查询
        User user = userMapper.findUserByPhoneOrName(dto.getName());
        if (user == null) {
            // 证明用户名或者手机号 有问题查不到
            return R.fail("用户名或者手机号 有误！");
        }
        // 能查到信息
        // 把前端传递过来的密码 进行加密 和数据库中的加密过后的密码对比
        String str = MD5.create().digestHex(user.getName() + "_" + dto.getPassword());
        if (!user.getPassword().equals(str)) {
            // 没对比成功
            // 记录失败次数
            String error_cs = stringRedisTemplate.opsForValue().get("login_error_" + dto.getName());
            if (error_cs != null) {
                int i = Integer.valueOf(error_cs);
                if (i < 3) {
                    i++;
                    stringRedisTemplate.opsForValue().set("login_error_" + dto.getName(), i + "", 0);
                    if (i == 3) {
                        stringRedisTemplate.opsForValue().set("lock_" + dto.getName(), "1", 1, TimeUnit.HOURS);
                    }
                }
            } else {
                // 初始化一次
                stringRedisTemplate.opsForValue().set("login_error_" + dto.getName(), "1", 5, TimeUnit.MINUTES);
            }
            return R.fail("密码有误！");
        }
        // 证明 登录成功！（1. 签发token  2. 封装用户信息）
        // 为了保证不同的用户使用不同的token 专属的
        String token = user.getName();

        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("user", user);
        resultMap.put("token", token);
        return R.ok(resultMap);
    }
}
